import React, {
    PureComponent,
    useRef,
    useState,
    useCallback,
    useContext,
    useEffect,
    useMemo
} from 'react'
import * as Hls from 'hls.js'
import Context from '@/config/context'
import Barrage from './Barrage'
import { getBarrages } from 'api/base'
import classnames from 'classnames'
import { formatDuration } from 'utils/index'
import './index.scss'

function VideoPlayer(props) {
    const { live = false, isLive = false, liveTime = 0, video } = props
    const videoRef = useRef()
    const barrageRef = useRef()
    // 当前播放时间ref
    const currentTimeRef = useRef()
    // 播放进度ref
    const progressRef = useRef()
    // 直播时长ref
    const liveDurationRef = useRef()
    const [paused, setPaused] = useState(true)
    const [waiting, setWaiting] = useState(false)
    const [bswitch, setBswitch] = useState(true)
    const [isfull, setIsfull] = useState(false)

    const [finish, setFinish] = useState(false)
    const [isCover, setIsCover] = useState(true)
    const [showControl, setShowControl] = useState(false)
    const [isplay, setIsplay] = useState(false)
    const [canLive, setCanLive] = useState(() => isLive)
    const [barrages, setBarrages] = useState([])

    const [duration, setDuration] = useState(0)

    const { videoURL } = useContext(Context)

    const getVideoUrl = useCallback((url) => {
        url = encodeURIComponent(url)
        // 拼接播放源地址
        return `${videoURL}?video=${url}`
    })
    useEffect(() => {
        showControl ? setIsplay(true) : setIsplay(false)
    }, [showControl])
    useEffect(() => {
        initVideo()
    }, [barrages])
    const ibarrages = useMemo(() => {
        if (live) {
            getBarrages(video.cId).then((res) => {
                const barrages = []
                res.data.forEach((data) => {
                    barrages.push({
                        type: data.type === '1' ? 1 : 2,
                        color: '#' + Number(data.decimalColor).toString(16),
                        content: data.content,
                        time: Number(data.time)
                    })
                })
                setBarrages(barrages)
                return barrages
            })
        }
        return ''
    }, [video])
    const initVideo = useCallback(() => {
        const barrageComponent = barrageRef.current

        const videoDOM = videoRef.current
        const currentTimeDOM = currentTimeRef.current
        const progressDOM = progressRef.current
        // 调用play方法时触发
        videoDOM.addEventListener('play', play, true)

        // 暂停或者在缓冲后准备重新开始播放时触发
        videoDOM.addEventListener('playing', play, true)

        videoDOM.addEventListener('waiting', () => {
            setWaiting(true)
        })
        if (live) {
            if (liveTime) {
                //   设置直播时间
                const liveDurationDOM = this.liveDurationRef.current
                let liveDuration = (new Date().getTime() - this.props.liveTime) / 1000
                liveDurationDOM.innerHTML = formatDuration(liveDuration, '0#:##:##')
                setInterval(() => {
                    liveDuration += 1
                    liveDurationDOM.innerHTML = formatDuration(liveDuration, '0#:##:##')
                }, 1000)
                // m3u8
                if (videoDOM.canPlayType('application/vnd.apple.mpegurl')) {
                    videoDOM.src = video.url
                    videoDOM.addEventListener('canplay', () => {
                        videoDOM.play()
                    })
                    videoDOM.addEventListener('error', () => {
                        setCanLive(false)
                    })
                } else if (Hls.isSupported()) {
                    const hls = new Hls()
                    hls.loadSource(video.url)
                    hls.attachMedia(videoDOM)
                    hls.on(Hls.Events.MANIFEST_PARSED, () => {
                        videoDOM.play()
                    })
                    hls.on(Hls.Events.ERROR, (event, data) => {
                        if (data.fatal) {
                            if (
                                data.type === Hls.ErrorTypes.NETWORK_ERROR ||
                                data.response.code === 404
                            ) {
                                setCanLive(false)
                            }
                        }
                    })
                }
            }
        } else {
            videoDOM.addEventListener('timeupdate', () => {
                if (duration === 0) {
                    setDuration(videoDOM.duration)
                }
                currentTimeDOM.innerHTML = formatDuration(videoDOM.currentTime, '0#:##')
                const progress = (videoDOM.currentTime / videoDOM.duration) * 100
                progressDOM.style.width = `${progress}%`

                // if (bswitch) {
                //     const barrages = findBarrages(videoDOM.currentTime);
                //     barrages.forEach((barrage) => {
                //         // 发送弹幕
                //         if (barrageComponent) {
                //             barrageComponent.sendone(barrage);
                //         }
                //     });
                // }
            })
            videoDOM.addEventListener('ended', () => {
                currentTimeDOM.innerHTML = '00:00'
                progressDOM.style.width = '0'
                setPaused(true)
                setShowControl(false)
                setIsplay(false)
                setIsfull(false)
                setFinish(true)
                // 重新赋值弹幕列表
                setBarrages(ibarrages.slice())
                // 清除弹幕
                barrageComponent.clearall()
            })

            // 进度条
            let width = 0
            let left = 0
            let rate = 0
            progressDOM.addEventListener('touchstart', (e) => {
                e.stopPropagation()

                const progressWrapperDOM = progressDOM.parentElement
                width = progressWrapperDOM.offsetWidth
                left = progressWrapperDOM.getBoundingClientRect().left

                playOrPause()
            })
            progressDOM.addEventListener('touchmove', (e) => {
                e.preventDefault()

                const touch = e.touches[0]
                // 计算拖拽进度比例
                rate = (touch.clientX - left) / width
                if (rate > 1) {
                    rate = 1
                } else if (rate < 0) {
                    rate = 0
                }
                const currentTime = videoDOM.duration * rate
                progressDOM.style.width = `${rate * 100}%`
                currentTimeDOM.innerHTML = formatDuration(currentTime, '0#:##')
            })
            progressDOM.addEventListener('touchend', () => {
                videoDOM.currentTime = videoDOM.duration * rate

                playOrPause()
            })
        }
    })
    /**
     * 获取弹幕列表
     */

    /**
     * 根据时间查找弹幕
     */
    const findBarrages = useCallback((time) => {
        // 查找到的弹幕
        const ret = []
        // 查找到的弹幕索引
        const indexs = []
        let temp = barrages.slice(0)
        temp.forEach((barrage, index) => {
            // 换成整数秒
            if (parseInt(barrage.time, 10) === parseInt(time, 10)) {
                ret.push(barrage)
                indexs.push(index)
            }
        })
        indexs.forEach((index, i) => {
            // 删除掉已经查找到的弹幕
            temp.splice(index - i, 1)
        })
        setBarrages(temp)
        return ret
    })
    const play = useCallback(() => {
        setPaused(false)
        setIsCover(false)
        setWaiting(false)
    })
    const playOrPause = useCallback(() => {
        const videoDOM = videoRef.current
        if (paused) {
            videoDOM.play()
            setPaused(false)
            setIsplay(true)
            setFinish(false)
            setTimeout(() => {
                if (isplay) {
                    setShowControl(false)
                    setIsplay(false)
                }
            }, 3000)
        } else {
            videoDOM.pause()
            setPaused(true)
        }
    })
    const changePlayPosition = useCallback((e) => {
        e.stopPropagation()
        const progressWrapperDOM = e.currentTarget
        const left = progressWrapperDOM.getBoundingClientRect().left
        const progress = (e.clientX - left) / progressWrapperDOM.offsetWidth
        const videoDOM = videoRef.current
        videoDOM.currentTime = videoDOM.duration * progress
        videoDOM.play()
        setShowControl(false)

        setTimeout(() => {
            if (isplay) {
                setIsplay(false)
            }
        }, 3000)

        // 重新赋值弹幕列表
        // this.barrages = this.initBarrages.slice();
        setBarrages(ibarrages.slice())
        // 清除弹幕
        barrageRef.current.clearall()
    })
    useEffect(() => {
        if (isfull) {
            setShowControl(false)
            setIsplay(false)
        } else {
            setShowControl(true)
            setIsplay(true)
        }
    }, [isfull])
    useEffect(() => {
        if (barrageRef.current) {
            barrageRef.current.clearall()
        }
    }, [bswitch])
    return (
        <div className={`video-play ${isfull ? 'fullscreen' : ''}`}>
            <video
                src=""
                height="100%"
                width="100%"
                preload="auto"
                x5-playsinline="true"
                webkit-playsinline="true"
                playsInline={true}
                src={getVideoUrl(video.url)}
                style={{ display: isCover ? 'none' : 'block' }}
                ref={videoRef}
            ></video>
            <div className="barrage">
                <Barrage opacity={live === false ? 0.75 : 1} ref={barrageRef} />
            </div>
            <div
                className="controls"
                onClick={() => {
                    setShowControl((showControl) => !showControl)
                }}
            >
                <div
                    className={paused ? `play-button play` : `play-button pause`}
                    style={{ display: isplay ? 'block' : 'none' }}
                    onClick={(e) => {
                        e.stopPropagation()
                        playOrPause()
                    }}
                />
                <div
                    style={{ display: showControl ? 'block' : 'none' }}
                    className={classnames('control-bar', { livecontrol: !!live })}
                >
                    {live ? (
                        <div className="left" ref={liveDurationRef}></div>
                    ) : (
                        <React.Fragment>
                            <div className="left">
                                <span className="time" ref={currentTimeRef}>
                                    00:00
                                </span>
                                <span className="split">/</span>
                                <span className="total-duration">{duration}</span>
                            </div>
                            <div className="center">
                                <div
                                    className="progress-wrapper"
                                    onClick={(e) => {
                                        changePlayPosition(e)
                                    }}
                                >
                                    <div className="progress" ref={progressRef} />
                                </div>
                            </div>
                        </React.Fragment>
                    )}
                    <div className="right">
                        <div
                            className={bswitch ? `barrage-on` : `barrage-off`}
                            onClick={(e) => {
                                e.stopPropagation()
                                setBswitch((bswitch) => !bswitch)
                            }}
                        />
                        <div
                            className="play-full"
                            onClick={(e) => {
                                e.stopPropagation()
                                setIsfull((isfull) => !isfull)
                            }}
                        />
                    </div>
                </div>
            </div>
            <div className="cover" style={{ display: isCover ? 'block' : 'none' }}>
                {live ? (
                    <React.Fragment>
                        <img className="pic" src={video.cover} alt={video.title} />
                        <div className="pre-play">
                            <div
                                className="preview"
                                onClick={() => {
                                    playOrPause()
                                }}
                            />
                        </div>
                    </React.Fragment>
                ) : (
                    <React.Fragment>
                        <div className="cover-title">av{video.aId}</div>
                        <img className="pic" src={video.cover} alt={video.title} />
                        <div className="pre-play">
                            <div className="pre-duration">{video.duration}</div>
                            <div
                                className="preview"
                                onClick={() => {
                                    playOrPause()
                                }}
                            />
                        </div>
                    </React.Fragment>
                )}
            </div>
            {waiting ? (
                <div className="loading">
                    <div className="wrapper">
                        <img className="img" src={require('../../assets/images/loading.svg')} />
                        <span className="text">{live === false ? '正在缓冲' : ''}</span>
                    </div>
                </div>
            ) : null}
            {finish === true ? (
                <div className="finish-cover">
                    <img className="cover-pic" src={video.cover} alt={video.title} />
                    <div className="cover-wrapper">
                        <div
                            className="replay"
                            onClick={() => {
                                playOrPause()
                            }}
                        >
                            <i className="replay-icon" />
                            <span>重新播放</span>
                        </div>
                    </div>
                </div>
            ) : null}
            {live && !canLive ? (
                <div className="notice-cover">
                    <div className="notice-wrapper">
                        <i />
                        <span>闲置中...</span>
                    </div>
                </div>
            ) : null}
        </div>
    )
}

export default VideoPlayer
